/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package FEMSolver;

import BounderyPack.Bounderies;
import BounderyPack.Boundery;
import BounderyPack.BounderyNodePair;
import BounderyPack.DBoundery;
import BounderyPack.DirihletPair;
import BounderyPack.SortComparator;
import FEMShapeFunctions.FEMShapeFunction1ElementMatrixGenerator;
import HashMatrix2.HashMatrix2;
import MathLib.HashMatrix.Gauss;
import MathLib.HashMatrix.HashMatrix;
import HashMatrix2.LUFactorization; 
import Integration.IFunction2D;
import MathLib.HashMatrix.Xoleckuj;
import MathLib.triangulation.SaveStructures.Node;
import MathLib.triangulation.SaveStructures.Triangle;
import MathLib.triangulation.SaveStructures.TriangleL;
import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;
import syntaxanalyser.PostfiksXY;

/**
 *
 * @author mark_o
 */
public class FEMMainMatrixGenerator implements FEMGenerator{
    protected HashMatrix A;
    public HashMatrix2 A2;
    public HashMatrix2 A3;
    public  double[] b;
    protected String F = "sin(x)+cos(y)";
    protected double Kx;
    protected double Ky;
    protected double Pe;
    protected double Pekle;
    protected Bounderies Bounds;
    protected ArrayList<Node> NodeList;
    protected ArrayList<Triangle> TriangleList;
    private double[] tempPyankareF;
    public DirihletPair[] mas;
    public boolean key=false;
    public double eps=0.01;
    public double[] bLive;
    
    public FEMMainMatrixGenerator() {
        Bounds = new Bounderies();
    }

    public void setPe(double Pe) {
        this.Pe = Pe;
    }

    public void setPekle(double Pekle) {
        this.Pekle = Pekle;
    }
    
    public Bounderies getBounds() {
        return Bounds;
    }

    public void setBounds(Bounderies Bounds) {
        this.Bounds = Bounds;
    }

    public void setKx(double Kx) {
        this.Kx = Kx;
    }

    public void setKy(double Ky) {
        this.Ky = Ky;
    }

    public void setF(String F) {
        this.F = F;
    }

    public void Generate(){
        A = new HashMatrix(HashMatrix.HASH_TYPE, NodeList.size());
        b= new double[NodeList.size()];
        bLive= new double[NodeList.size()];
        
        for(int i=0;i<TriangleList.size();i++){
            TriangleL tr = (TriangleL) TriangleList.get(i);
            
            //A
            double[][] Ke = FEMElementMatrixGenerator.GenerateKe(NodeList.get(tr.A-1), NodeList.get(tr.B-1), NodeList.get(tr.C-1));
            double[][] Me = FEMElementMatrixGenerator.GenerateMe(NodeList.get(tr.A-1), NodeList.get(tr.B-1), NodeList.get(tr.C-1));
            

                A.setValue(tr.A-1, tr.A-1, A.getValue(tr.A-1, tr.A-1) + Ke[0][0]+Me[0][0]);
                A.setValue(tr.A-1, tr.B-1, A.getValue(tr.A-1, tr.B-1) + Ke[0][1]+Me[0][1]);
                A.setValue(tr.A-1, tr.C-1, A.getValue(tr.A-1, tr.C-1) + Ke[0][2]+Me[0][2]);

                A.setValue(tr.B-1, tr.A-1, A.getValue(tr.B-1, tr.A-1) + Ke[1][0]+Me[1][0]);
                A.setValue(tr.B-1, tr.B-1, A.getValue(tr.B-1, tr.B-1) + Ke[1][1]+Me[1][1]);
                A.setValue(tr.B-1, tr.C-1, A.getValue(tr.B-1, tr.C-1) + Ke[1][2]+Me[1][2]);

                A.setValue(tr.C-1, tr.A-1, A.getValue(tr.C-1, tr.A-1) + Ke[2][0]+Me[2][0]);
                A.setValue(tr.C-1, tr.B-1, A.getValue(tr.C-1, tr.B-1) + Ke[2][1]+Me[2][1]);
                A.setValue(tr.C-1, tr.C-1, A.getValue(tr.C-1, tr.C-1) + Ke[2][2]+Me[2][2]);
            
            
            
            //b
            double Fa;
            double Fb;
            double Fc;

            try {
                Fa = PostfiksXY.Calculate(F, NodeList.get(tr.A-1).x, NodeList.get(tr.A-1).y);
                Fb = PostfiksXY.Calculate(F, NodeList.get(tr.B-1).x, NodeList.get(tr.B-1).y);
                Fc = PostfiksXY.Calculate(F, NodeList.get(tr.C-1).x, NodeList.get(tr.C-1).y);
                b[tr.A-1] = Me[0][0]*Fa+Me[0][1]*Fb+Me[0][2]*Fc;
                b[tr.B-1] = Me[1][0]*Fa+Me[1][1]*Fb+Me[1][2]*Fc;
                b[tr.C-1] = Me[2][0]*Fa+Me[2][1]*Fb+Me[2][2]*Fc;

            } catch (Exception ex) {
                Fa = 0;
                Fb = 0;
                Fc = 0;
            }
        }

        /*for(int i = 0;i<A2.getN();i++){
        for(int j = 0;j<A2.getN();j++){
        System.out.print(A2.getValue(i, j)+" ");
        }
        System.out.println(";");
        }*/
    }

    public void GenerateLU(){
        A2 = new HashMatrix2(HashMatrix2.HASH_TYPE, NodeList.size());
        b= new double[NodeList.size()];
        bLive= new double[NodeList.size()];
        FEMElementMatrixGenerator.kx = Kx;
        FEMElementMatrixGenerator.ky = Ky;

        FEMElementMatrixGenerator.Pex = Pekle;
        FEMElementMatrixGenerator.Pey = Pekle;
        FEMShapeFunction1ElementMatrixGenerator femgen = new FEMShapeFunction1ElementMatrixGenerator();
        femgen.setKx(Kx);
        femgen.setKy(Ky);
        
        for(int i=0;i<TriangleList.size();i++){
            TriangleL tr = (TriangleL) TriangleList.get(i);
            
            //A
            double[][] Ke = FEMElementMatrixGenerator.GenerateKe(NodeList.get(tr.A-1), NodeList.get(tr.B-1), NodeList.get(tr.C-1));
            double[][] Me = FEMElementMatrixGenerator.GenerateMe(NodeList.get(tr.A-1), NodeList.get(tr.B-1), NodeList.get(tr.C-1));
            double[][] Pek = FEMElementMatrixGenerator.GeneratePe(NodeList.get(tr.A-1), NodeList.get(tr.B-1), NodeList.get(tr.C-1));
            double[][] PyankareMatrix = this.generateHme(tr);

            femgen.setA(NodeList.get(tr.A-1));
            femgen.setB(NodeList.get(tr.B-1));
            femgen.setC(NodeList.get(tr.C-1));
            femgen.update();
            //double[][] Me1 = femgen.GenerateMe();
            //double[][] Ke1 = femgen.GenerateKe();


                A2.setValue(tr.A-1, tr.A-1, A2.getValue(tr.A-1, tr.A-1) + Ke[0][0]+Pe*Me[0][0] + Pek[0][0] + PyankareMatrix[0][0]);
                A2.setValue(tr.A-1, tr.B-1, A2.getValue(tr.A-1, tr.B-1) + Ke[0][1]+Pe*Me[0][1] + Pek[0][1] + PyankareMatrix[0][1]);
                A2.setValue(tr.A-1, tr.C-1, A2.getValue(tr.A-1, tr.C-1) + Ke[0][2]+Pe*Me[0][2] + Pek[0][2] + PyankareMatrix[0][2]);

                A2.setValue(tr.B-1, tr.A-1, A2.getValue(tr.B-1, tr.A-1) + Ke[1][0]+Pe*Me[1][0] + Pek[1][0] + PyankareMatrix[1][0]);
                A2.setValue(tr.B-1, tr.B-1, A2.getValue(tr.B-1, tr.B-1) + Ke[1][1]+Pe*Me[1][1] + Pek[1][1] + PyankareMatrix[1][1]);
                A2.setValue(tr.B-1, tr.C-1, A2.getValue(tr.B-1, tr.C-1) + Ke[1][2]+Pe*Me[1][2] + Pek[1][2] + PyankareMatrix[1][2]);

                A2.setValue(tr.C-1, tr.A-1, A2.getValue(tr.C-1, tr.A-1) + Ke[2][0]+Pe*Me[2][0] + Pek[2][0] + PyankareMatrix[2][0]);
                A2.setValue(tr.C-1, tr.B-1, A2.getValue(tr.C-1, tr.B-1) + Ke[2][1]+Pe*Me[2][1] + Pek[2][1] + PyankareMatrix[2][1]);
                A2.setValue(tr.C-1, tr.C-1, A2.getValue(tr.C-1, tr.C-1) + Ke[2][2]+Pe*Me[2][2] + Pek[2][2] + PyankareMatrix[2][2]);

            double Fa;
            double Fb;
            double Fc;

            try {
                Fa = PostfiksXY.Calculate(F, NodeList.get(tr.A-1).x, NodeList.get(tr.A-1).y);
                Fb = PostfiksXY.Calculate(F, NodeList.get(tr.B-1).x, NodeList.get(tr.B-1).y);
                Fc = PostfiksXY.Calculate(F, NodeList.get(tr.C-1).x, NodeList.get(tr.C-1).y);
               

            } catch (Exception ex) {
                System.out.print("Помилка в постфіксі");
                Fa = 0;
                Fb = 0;
                Fc = 0;
            }
                double[] tmpNayman = getNaymanCond(tr);

                
                double Atr = FEMElementMatrixGenerator.ComputeTriangleArea(NodeList.get(tr.A-1), NodeList.get(tr.B-1), NodeList.get(tr.C-1));


                double[] Fr = femgen.GenerateF(new IFunction2D() {

                public double calculate(double x, double y) {
                    try {
                        return PostfiksXY.Calculate(F, x, y);
                    } catch (Exception ex) {
                        Logger.getLogger(FEMQuadraticTRMainMatrixGenerator.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    return 0;
                }

                public double calculateDerivatyX(double x, double y) {
                    throw new UnsupportedOperationException("Not supported yet.");
                }

                public double calculateDerivatyY(double x, double y) {
                    throw new UnsupportedOperationException("Not supported yet.");
                }
            });

               b[tr.A-1]+= Fa/3.0*Atr + tempPyankareF[0] - tmpNayman[0];
               b[tr.B-1]+= Fb/3.0*Atr + tempPyankareF[1] - tmpNayman[1];
               b[tr.C-1]+= Fc/3.0*Atr + tempPyankareF[2] - tmpNayman[2];

        }
        ApplyDirihlet2();
        for (int i = 0; i < b.length; i++) {
			for (int j = 0; j < b.length; j++) {
				System.out.print(A2.getValue(i, j)+"\t\t");
			}
			System.out.print("\n");
		}

    }

    private double[] getNaymanCond(TriangleL tr){
        double i = 0,
               j = 0,
               k = 0;
        double h = 0,sigma = 0;
        Node vA = NodeList.get(tr.A-1),
             vB = NodeList.get(tr.B-1),
             vC = NodeList.get(tr.C-1);
        boolean a1=false,a2=false,a3=false;
        for (int index = 0; index < Bounds.getNayman().size(); index++) {
            Boundery boundery = Bounds.getNayman().get(index);

            i=0;j=0;k=0;

            for (int iter = 0; iter < boundery.getNodeList().size(); iter++) {
                BounderyNodePair temp = boundery.getNodeList().get(iter);

                if(temp.contains(vA, vB)){
                    i=1.0;
                    j=1.0;
                    a1=true;
                }
                if(temp.contains(vA, vC)){
                    i=1.0;
                    k=1.0;
                    a2=true;
                }
                if(temp.contains(vC, vB)){
                    k=1.0;
                    j=1.0;
                    a3=true;
                }

            }
            if(i+j+k==2){
                h = Double.parseDouble(boundery.getParams().h);
                sigma = Double.parseDouble(boundery.getParams().g);
                double length = i*j*( Math.sqrt( (vA.x - vB.x)*(vA.x - vB.x) + (vA.y - vB.y)*(vA.y - vB.y) ) ) +
                        k*j*( Math.sqrt( (vC.x - vB.x)*(vC.x - vB.x) + (vC.y - vB.y)*(vC.y - vB.y) ) ) +
                        i*k*( Math.sqrt( (vA.x - vC.x)*(vA.x - vC.x) + (vA.y - vC.y)*(vA.y - vC.y) ) );

                //tempPyankareF = new double[]{i*h*sigma*length/2.0, j*h*sigma*length/2.0, k*h*sigma*length/2.0};
                    length*=h/6.0;
                return new double[]{
                    i/2.0*h*length , j/2.0*h*length , k/2.0*h*length
                };
            }else{
                if(i+j+k>2){
                    h = Double.parseDouble(boundery.getParams().h);
                    sigma = Double.parseDouble(boundery.getParams().g);
                    double[] res = new  double[3];
                    if(a1){
                        double length = ( Math.sqrt( (vA.x - vB.x)*(vA.x - vB.x) + (vA.y - vB.y)*(vA.y - vB.y) ) );
                        //length*;
                        res[0] = h*length/2.0;
                        res[1] = h*length/2.0;
                        res[2] = 0.0;
                    }
                    if(a2){
                        double length = ( Math.sqrt( (vA.x - vC.x)*(vA.x - vC.x) + (vA.y - vC.y)*(vA.y - vC.y) ) );
                        //length*;
                        res[0]+= h*length/2.0;
                        res[1]+= 0.0;
                        res[2]+= h*length/2.0;
                    }
                    if(a3){
                        double length = ( Math.sqrt( (vC.x - vB.x)*(vC.x - vB.x) + (vC.y - vB.y)*(vC.y - vB.y) ) );
                        //length*;
                        res[0]+= 0.0;
                        res[1]+= h*length/2.0;
                        res[2]+= h*length/2.0;
                    }
                    return res;
                } 
            }
        }
        return new double[]{
                        0.0 , 0.0 , 0.0
                    };
    }


    private void ApplyDirihlet(){
        ArrayList<DirihletPair> tempList = new ArrayList<DirihletPair>();
        for (int index = 0; index < Bounds.getDirihlet().size(); index++) {
            DBoundery boundery = Bounds.getDirihlet().get(index);
            for (int iter = 0; iter < boundery.getNodeList().size(); iter++) {
                try {
                    //this.Set(boundery.getNodeList().get(iter).Number, );
                    tempList.add(new DirihletPair(boundery.getNodeList().get(iter).Number, PostfiksXY.Calculate("(" + boundery.getParams().g + ")/(" + boundery.getParams().h + ")", boundery.getNodeList().get(iter).x, boundery.getNodeList().get(iter).y)));
                } catch (Exception ex) {
                    Logger.getLogger(FEMMainMatrixGenerator.class.getName()).log(Level.SEVERE, null, ex);
                    System.out.print("помилка");
                }
            }
        }
        mas = new DirihletPair[tempList.size()];
        tempList.toArray(mas);
        Arrays.sort(mas, new SortComparator());

        /*for (int i = 0; i < mas.length; i++) {
        System.out.println(mas[i]);
        }*/

        for (int i = mas.length-1; i >-1 ; i--) {
            DirihletPair dirihletPair = mas[i];

            for (int j = 0; j < A2.getN(); j++) {
                b[j]-=dirihletPair.getValue()*A2.getValue(j, dirihletPair.getNodeNumber());
                //A2.setValue(j, dirihletPair.getNodeNumber(), 0);
            }


            //видалення непотрібного ....
                double[] dtemp = new double[b.length-1];
                for (int j = 0; j < mas[i].getNodeNumber(); j++) {
                    dtemp[j] = b[j];
                }
                for (int j = mas[i].getNodeNumber()+1; j < b.length; j++) {
                    dtemp[j-1] = b[j];
                }
                b = dtemp;
                A2.removeRow(mas[i].getNodeNumber());
//                if(key){
//                    A3.removeRow(mas[i].getNodeNumber());
//                }

                ArrayList<DBoundery> tmp= Bounds.getNapivPronukluvist();
                for (int j = 0; j < tmp.size(); j++) {
                DBoundery dBoundery = tmp.get(j);
                    for (int k = 0; k < dBoundery.getNodeList().size(); k++) {
                        Node node = dBoundery.getNodeList().get(k);
                        if(node.Number>mas[i].getNodeNumber()){
                            node.Number--;
                        }
                    }
                }

                ArrayList<Boundery> tmp2= Bounds.getNapivPronukluvist2();
                for (int j = 0; j < tmp2.size(); j++) {
                Boundery Boundery = tmp2.get(j);
                    for (int k = 0; k < Boundery.getNodeList().size(); k++) {
                        BounderyNodePair nodePair = Boundery.getNodeList().get(k);
                        if(nodePair.getA().Number>mas[i].getNodeNumber()){
                            nodePair.getA().Number--;
                        }
                        if(nodePair.getB().Number>mas[i].getNodeNumber()){
                            nodePair.getB().Number--;
                        }
                    }
                }

        }

    }

    private void ApplyDirihlet2(){
        ArrayList<DirihletPair> tempList = new ArrayList<DirihletPair>();
        for (int index = 0; index < Bounds.getDirihlet().size(); index++) {
            DBoundery boundery = Bounds.getDirihlet().get(index);
            for (int iter = 0; iter < boundery.getNodeList().size(); iter++) {
                try {
                    //this.Set(boundery.getNodeList().get(iter).Number, );
                    tempList.add(new DirihletPair(boundery.getNodeList().get(iter).Number, PostfiksXY.Calculate("(" + boundery.getParams().g + ")/(" + boundery.getParams().h + ")", boundery.getNodeList().get(iter).x, boundery.getNodeList().get(iter).y)));
                } catch (Exception ex) {
                    Logger.getLogger(FEMMainMatrixGenerator.class.getName()).log(Level.SEVERE, null, ex);
                    System.out.print("помилка");
                }
            }
        }
        mas = new DirihletPair[tempList.size()];
        tempList.toArray(mas);
        Arrays.sort(mas, new SortComparator());

        /*for (int i = 0; i < mas.length; i++) {
        System.out.println(mas[i]);
        }*/

        for (int i = mas.length-1; i >-1 ; i--) {
            DirihletPair dirihletPair = mas[i];

            for (int j = 0; j < A2.getN(); j++) {
                b[j]-=dirihletPair.getValue()*A2.getValue(j, dirihletPair.getNodeNumber());
                //A2.setValue(j, dirihletPair.getNodeNumber(), 0);
            }


            //видалення непотрібного ....
                //double[] dtemp = new double[b.length-1];
                //for (int j = 0; j < mas[i].getNodeNumber(); j++) {
                //    dtemp[j] = b[j];
                //}
                //for (int j = mas[i].getNodeNumber()+1; j < b.length; j++) {
                //    dtemp[j-1] = b[j];
                //}
                //b = dtemp;
            int pos = mas[i].getNodeNumber();
            b[pos] = dirihletPair.getValue();
            ArrayList<Integer> poList = A2.getJRowIndex(pos);
            for (int j = 0; j < poList.size(); j++) {
                A2.setValue(pos, poList.get(j), 0.0);
            }
            A2.setValue(pos, pos, 1.0);

            //    A2.removeRow(mas[i].getNodeNumber());
//                if(key){
//                    A3.removeRow(mas[i].getNodeNumber());
//                }

                //ArrayList<DBoundery> tmp= Bounds.getNapivPronukluvist();
                //for (int j = 0; j < tmp.size(); j++) {
                //DBoundery dBoundery = tmp.get(j);
                //    for (int k = 0; k < dBoundery.getNodeList().size(); k++) {
                //        Node node = dBoundery.getNodeList().get(k);
                //        if(node.Number>mas[i].getNodeNumber()){
                //            node.Number--;
                //        }
                //    }
                //}

                //ArrayList<Boundery> tmp2= Bounds.getNapivPronukluvist2();
                //for (int j = 0; j < tmp2.size(); j++) {
                //Boundery Boundery = tmp2.get(j);
                //    for (int k = 0; k < Boundery.getNodeList().size(); k++) {
                //        BounderyNodePair nodePair = Boundery.getNodeList().get(k);
                //        if(nodePair.getA().Number>mas[i].getNodeNumber()){
                //            nodePair.getA().Number--;
                //        }
                //        if(nodePair.getB().Number>mas[i].getNodeNumber()){
                //            nodePair.getB().Number--;
                //        }
                //    }
                //}

        }

    }

    private double[][] generateHme(TriangleL tr){
        double i = 0,
               j = 0,
               k = 0;
        double h = 0,sigma = 0;
        Node vA = NodeList.get(tr.A-1),
             vB = NodeList.get(tr.B-1),
             vC = NodeList.get(tr.C-1);
        boolean a1=false,a2=false,a3=false;
        for (int index = 0; index < Bounds.getPyankare().size(); index++) {
            Boundery boundery = Bounds.getPyankare().get(index);

            i=0;j=0;k=0;

            for (int iter = 0; iter < boundery.getNodeList().size(); iter++) {
                BounderyNodePair temp = boundery.getNodeList().get(iter);

                if(temp.contains(vA, vB)){
                    i=1.0;
                    j=1.0;
                    a1=true;
                }
                if(temp.contains(vA, vC)){
                    i=1.0;
                    k=1.0;
                    a2=true;
                }
                if(temp.contains(vC, vB)){
                    k=1.0;
                    j=1.0;
                    a3=true;
                }

            }
            if(i+j+k==2){
                h = Double.parseDouble(boundery.getParams().h);
                sigma = Double.parseDouble(boundery.getParams().sigma);
                double length = i*j*( Math.sqrt( (vA.x - vB.x)*(vA.x - vB.x) + (vA.y - vB.y)*(vA.y - vB.y) ) ) +
                                k*j*( Math.sqrt( (vC.x - vB.x)*(vC.x - vB.x) + (vC.y - vB.y)*(vC.y - vB.y) ) ) +
                                i*k*( Math.sqrt( (vA.x - vC.x)*(vA.x - vC.x) + (vA.y - vC.y)*(vA.y - vC.y) ) );

                    tempPyankareF = new double[]{i*h*sigma*length/2.0, j*h*sigma*length/2.0, k*h*sigma*length/2.0};
                    length*=h/6.0;
                return new double[][]{
                    { i*2*length , i*j*length , i*k*length},
                    { i*j*length , j*2*length , j*k*length},
                    { i*k*length , k*j*length , k*2*length}
                };
            }else{
                if(i+j+k>2){
                    h = Double.parseDouble(boundery.getParams().h);
                    sigma = Double.parseDouble(boundery.getParams().sigma);
                    tempPyankareF = new double[3];
                    double[][] res = new  double[3][3];
                    if(a1){
                        double length = ( Math.sqrt( (vA.x - vB.x)*(vA.x - vB.x) + (vA.y - vB.y)*(vA.y - vB.y) ) );
                        //length*;
                        tempPyankareF[0] = h*sigma*length/2.0;
                        tempPyankareF[1] = h*sigma*length/2.0;
                        length*=h/6.0;
                        res[0][0] = length*2;   res[0][1] = length;
                        res[1][0] = length;     res[1][1] = length*2;
                    }
                    if(a2){
                        double length = ( Math.sqrt( (vA.x - vC.x)*(vA.x - vC.x) + (vA.y - vC.y)*(vA.y - vC.y) ) );
                        //length*;
                        tempPyankareF[0]+= h*sigma*length/2.0;
                        tempPyankareF[2]+= h*sigma*length/2.0;
                        length*=h/6.0;
                        res[0][0]+= length*2;   res[0][2]+= length;
                        res[2][0]+= length;     res[2][2]+= length*2;
                    }
                    if(a3){
                        double length = ( Math.sqrt( (vC.x - vB.x)*(vC.x - vB.x) + (vC.y - vB.y)*(vC.y - vB.y) ) );
                        //length*;
                        tempPyankareF[1]+= h*sigma*length/2.0;
                        tempPyankareF[2]+= h*sigma*length/2.0;
                        length*=h/6.0;
                        res[1][1]+= length*2;   res[1][2]+= length;
                        res[2][1]+= length;     res[2][2]+= length*2;
                    }

                    return res;
                }
            }
        }

        /*for (int index = 0; index < Bounds.getPyankare().size(); index++) {
        Boundery boundery = Bounds.getPyankare().get(index);

        i=0;j=0;k=0;

        for (int iter = 0; iter < boundery.getNodeList().size(); iter++) {
        Node temp = boundery.getNodeList().get(iter);

        if(vA.equals(temp)){
        i=1.0;
        }
        if(vB.equals(temp)){
        j=1.0;
        }
        if(vC.equals(temp)){
        k=1.0;
        }

        }
        if(i+j+k>1){
        h = Double.parseDouble(boundery.getParams().h);
        sigma = Double.parseDouble(boundery.getParams().sigma);
        break;
        }

        }

        double length = i*j*( Math.sqrt( (vA.x - vB.x)*(vA.x - vB.x) + (vA.y - vB.y)*(vA.y - vB.y) ) ) +
        k*j*( Math.sqrt( (vC.x - vB.x)*(vC.x - vB.x) + (vC.y - vB.y)*(vC.y - vB.y) ) ) +
        i*k*( Math.sqrt( (vA.x - vC.x)*(vA.x - vC.x) + (vA.y - vC.y)*(vA.y - vC.y) ) );

        tempPyankareF = new double[]{i*h*sigma*length/2.0, j*h*sigma*length/2.0, k*h*sigma*length/2.0};
        length*=h/6.0;
        return new double[][]{
        { i*2*length , i*j*length , i*k*length},
        { i*j*length , j*2*length , j*k*length},
        { i*k*length , k*j*length , k*2*length}
        };*/
        tempPyankareF = new double[3];
        return new double[][]{
                        {0.0 , 0.0 , 0.0},
                        {0.0 , 0.0 , 0.0},
                        {0.0 , 0.0 , 0.0}
                    };

    }

        private double[][] generateNapiv(TriangleL tr){
        double i = 0,
               j = 0,
               k = 0;
        double h = 0,sigma = 0;
        Node vA = NodeList.get(tr.A-1),
             vB = NodeList.get(tr.B-1),
             vC = NodeList.get(tr.C-1);
        boolean a1=false,a2=false,a3=false;
        for (int index = 0; index < Bounds.getNapivPronukluvist2().size(); index++) {
            Boundery boundery = Bounds.getNapivPronukluvist2().get(index);

            i=0;j=0;k=0;

            for (int iter = 0; iter < boundery.getNodeList().size(); iter++) {
                BounderyNodePair temp = boundery.getNodeList().get(iter);

                if(temp.contains(vA, vB)){
                    i=1.0;
                    j=1.0;
                    a1=true;
                }
                if(temp.contains(vA, vC)){
                    i=1.0;
                    k=1.0;
                    a2=true;
                }
                if(temp.contains(vC, vB)){
                    k=1.0;
                    j=1.0;
                    a3=true;
                }

            }
            if(i+j+k==2){
                h = Double.parseDouble(boundery.getParams().h);
                sigma = Double.parseDouble(boundery.getParams().sigma);
                double length = i*j*( Math.sqrt( (vA.x - vB.x)*(vA.x - vB.x) + (vA.y - vB.y)*(vA.y - vB.y) ) ) +
                                k*j*( Math.sqrt( (vC.x - vB.x)*(vC.x - vB.x) + (vC.y - vB.y)*(vC.y - vB.y) ) ) +
                                i*k*( Math.sqrt( (vA.x - vC.x)*(vA.x - vC.x) + (vA.y - vC.y)*(vA.y - vC.y) ) );

                    tempPyankareF = new double[]{i*h*sigma*length/2.0, j*h*sigma*length/2.0, k*h*sigma*length/2.0};
                    length*=h/6.0;
                return new double[][]{
                    { i*2*length , i*j*length , i*k*length},
                    { i*j*length , j*2*length , j*k*length},
                    { i*k*length , k*j*length , k*2*length}
                };
            }else{
                if(i+j+k>2){
                    h = Double.parseDouble(boundery.getParams().h);
                    sigma = Double.parseDouble(boundery.getParams().sigma);
                    tempPyankareF = new double[3];
                    double[][] res = new  double[3][3];
                    if(a1){
                        double length = ( Math.sqrt( (vA.x - vB.x)*(vA.x - vB.x) + (vA.y - vB.y)*(vA.y - vB.y) ) );
                        //length*;
                        tempPyankareF[0] = h*sigma*length/2.0;
                        tempPyankareF[1] = h*sigma*length/2.0;
                        length*=h/6.0;
                        res[0][0] = length*2;   res[0][1] = length;
                        res[1][0] = length;     res[1][1] = length*2;
                    }
                    if(a2){
                        double length = ( Math.sqrt( (vA.x - vC.x)*(vA.x - vC.x) + (vA.y - vC.y)*(vA.y - vC.y) ) );
                        //length*;
                        tempPyankareF[0]+= h*sigma*length/2.0;
                        tempPyankareF[2]+= h*sigma*length/2.0;
                        length*=h/6.0;
                        res[0][0]+= length*2;   res[0][2]+= length;
                        res[2][0]+= length;     res[2][2]+= length*2;
                    }
                    if(a3){
                        double length = ( Math.sqrt( (vC.x - vB.x)*(vC.x - vB.x) + (vC.y - vB.y)*(vC.y - vB.y) ) );
                        //length*;
                        tempPyankareF[1]+= h*sigma*length/2.0;
                        tempPyankareF[2]+= h*sigma*length/2.0;
                        length*=h/6.0;
                        res[1][1]+= length*2;   res[1][2]+= length;
                        res[2][1]+= length;     res[2][2]+= length*2;
                    }

                    return res;
                }
            }
        }

        /*for (int index = 0; index < Bounds.getPyankare().size(); index++) {
        Boundery boundery = Bounds.getPyankare().get(index);

        i=0;j=0;k=0;

        for (int iter = 0; iter < boundery.getNodeList().size(); iter++) {
        Node temp = boundery.getNodeList().get(iter);

        if(vA.equals(temp)){
        i=1.0;
        }
        if(vB.equals(temp)){
        j=1.0;
        }
        if(vC.equals(temp)){
        k=1.0;
        }

        }
        if(i+j+k>1){
        h = Double.parseDouble(boundery.getParams().h);
        sigma = Double.parseDouble(boundery.getParams().sigma);
        break;
        }

        }

        double length = i*j*( Math.sqrt( (vA.x - vB.x)*(vA.x - vB.x) + (vA.y - vB.y)*(vA.y - vB.y) ) ) +
        k*j*( Math.sqrt( (vC.x - vB.x)*(vC.x - vB.x) + (vC.y - vB.y)*(vC.y - vB.y) ) ) +
        i*k*( Math.sqrt( (vA.x - vC.x)*(vA.x - vC.x) + (vA.y - vC.y)*(vA.y - vC.y) ) );

        tempPyankareF = new double[]{i*h*sigma*length/2.0, j*h*sigma*length/2.0, k*h*sigma*length/2.0};
        length*=h/6.0;
        return new double[][]{
        { i*2*length , i*j*length , i*k*length},
        { i*j*length , j*2*length , j*k*length},
        { i*k*length , k*j*length , k*2*length}
        };*/
        tempPyankareF = new double[3];
        return new double[][]{
                        {0.0 , 0.0 , 0.0},
                        {0.0 , 0.0 , 0.0},
                        {0.0 , 0.0 , 0.0}
                    };

    }


    public void Set(int pos,double f){
        this.A2.setValue(pos, pos, DrawingPanels.FEM_DRAWING_CONSTANTS.FEM_MULTI_CONST_BOUNDERY);
        this.b[pos]+=f*DrawingPanels.FEM_DRAWING_CONSTANTS.FEM_MULTI_CONST_BOUNDERY;
    }


    public void SolveG(String outPath) throws FileNotFoundException{
        Gauss g  = new Gauss(A);
        double[] res = g.calculate(b);
        PrintWriter pw = new PrintWriter(new BufferedOutputStream(new FileOutputStream(outPath)));
        pw.println(res.length);
        for(int i=0;i<res.length;i++){
            pw.println(res[i]);
        }
        pw.close();
    }

    public void SolveX(String outPath) throws FileNotFoundException{
        Xoleckuj g  = new Xoleckuj(A);
        double[] res = g.calculate(b);
        PrintWriter pw = new PrintWriter(new BufferedOutputStream(new FileOutputStream(outPath)));
        pw.println(res.length);
        for(int i=0;i<res.length;i++){
            pw.println(res[i]);
        }
        pw.close();
    }

    public void SolveLU(String outPath) throws FileNotFoundException{
        LUFactorization g = new LUFactorization(A2);
        double[] res = g.calculate(b);


        for (int i = 0; i < res.length; i++) {
            double d = res[i];
            System.out.println(d);
        }


        PrintWriter pw = new PrintWriter(new BufferedOutputStream(new FileOutputStream(outPath)));
        pw.println(res.length + mas.length);
        if(mas.length>0){
            int j;
            for (j = 0; j < mas[0].getNodeNumber(); j++) {
                pw.println(res[j]);
            }

            for(int i=0; i<mas.length-1; i++){
                int k=0;
                pw.println(mas[i].getValue());
                while(mas[i+1].getNodeNumber() - mas[i].getNodeNumber()-k!=1){
                    pw.println(res[j]);
                    j++;
                    k++;
                }
            }

            pw.println(mas[mas.length-1].getValue());

            for (int i = j; i < res.length; i++) {
                pw.println(res[i]);
            }
        }else{
            for (int i = 0; i < res.length; i++) {
                pw.println(res[i]);
            }
        }
        pw.close();
    }

    public void setTriangleList(ArrayList<Triangle> tr) {
        this.TriangleList = tr;
    }

    public void setNodeList(ArrayList<Node> nd) {
        this.NodeList = nd;
    }
    
}
